package com.gant.controller;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gant.util.AlertUtil;
import com.gant.view.HighlightTreeCell;
import com.gant.view.MainView;
import javafx.application.Platform;
import javafx.scene.control.*;
import javafx.stage.FileChooser;
import javafx.stage.Stage;

import java.io.File;
import java.io.IOException;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;

public class JsonController {
    // 成员变量
    private JsonNode rootNode;
    private TreeItem<String> currentRootItem;

    private final Deque<TreeItem<String>> navigationStack = new ArrayDeque<>();
    private List<TreeItem<String>> searchMatches = new ArrayList<>();

    private int currentPage = 1;
    private int pageSize = 100;
    private int totalPages = 1;

    private MainView mainView;

    public JsonController(MainView mainView) {
        this.mainView = mainView;
    }

    //=== 核心业务方法 ===//

    // 构建JSON树方法
    private TreeItem<String> buildTree(JsonNode node, String key) {
        TreeItem<String> item = new TreeItem<>(key);
        if (node.isObject()) {
            node.fields().forEachRemaining(entry ->
                    item.getChildren().add(buildTree(entry.getValue(), entry.getKey()))
            );
        } else if (node.isArray()) {
            int index = 0;
            for (JsonNode elem : node) {
                item.getChildren().add(buildTree(elem, "[" + index++ + "]"));
            }
        } else {
            item.setValue(key + ": " + node.asText());
        }
        return item;
    }

    // 更新分页信息
    public void updatePagination() {
        try {
            pageSize = Integer.parseInt(mainView.getPageSizeField().getText());
            pageSize = Math.max(1, pageSize);
        } catch (Exception e) {
            pageSize = 100;
        }

        int itemCount = currentRootItem.getChildren().size();
        totalPages = (int) Math.ceil((double) itemCount / pageSize);
        totalPages = Math.max(1, totalPages);

        currentPage = Math.max(1, Math.min(currentPage, totalPages));
        Platform.runLater(() -> {
            mainView.getPageInfoLabel().setText("Page: " + currentPage + "/" + totalPages);
            mainView.getPrevPageButton().setDisable(currentPage <= 1);
            mainView.getNextPageButton().setDisable(currentPage >= totalPages);
        });
    }

    // 收集匹配项
    private void collectMatches(TreeItem<String> item, String keyword, List<TreeItem<String>> matches) {
        if (item.getValue().toLowerCase().contains(keyword)) {
            matches.add(item);
        }
        for (TreeItem<String> child : item.getChildren()) {
            collectMatches(child, keyword, matches);
        }
    }

    // 展开父节点
    private void expandParents(TreeItem<String> item) {
        Deque<TreeItem<String>> stack = new ArrayDeque<>();
        TreeItem<String> parent = item.getParent();
        while (parent != null) {
            stack.push(parent);
            parent = parent.getParent();
        }
        while (!stack.isEmpty()) {
            TreeItem<String> node = stack.pop();
            node.setExpanded(true);
        }
    }


    // 加载分页数据
    public void loadPage(int page) {
        if (currentRootItem == null) return;

        List<TreeItem<String>> children = currentRootItem.getChildren();
        int start = (page - 1) * pageSize;
        int end = Math.min(start + pageSize, children.size());

        TreeItem<String> pageRoot = new TreeItem<>(currentRootItem.getValue());
        for (int i = start; i < end; i++) {
            TreeItem<String> child = children.get(i);
            child.setExpanded(false);
            pageRoot.getChildren().add(child);
        }

        Platform.runLater(() -> {
            mainView.getJsonTreeView().setRoot(pageRoot);
            pageRoot.setExpanded(true);
            mainView.getTotalItemsLabel().setText("Total Items: " + children.size());
        });
    }

    // 返回导航
    public void navigateBack() {
        if (!navigationStack.isEmpty()) {
            currentRootItem = navigationStack.pop();  // 正确弹出历史项
            currentPage = 1;
            updatePagination();
            loadPage(currentPage);
            collapseAllChildren(currentRootItem);

            // 强制刷新树视图
            Platform.runLater(() -> {
                mainView.getJsonTreeView().refresh();
                mainView.getJsonTreeView().getRoot().setExpanded(true);
            });
        }
    }

    // 折叠所有子节点
    private void collapseAllChildren(TreeItem<String> item) {
        item.setExpanded(false);
        item.getChildren().forEach(this::collapseAllChildren);
    }

    public void handleOpenFile(Stage stage) {
        FileChooser fileChooser = new FileChooser();
        fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("JSON Files", "*.json"));

        File file = fileChooser.showOpenDialog(stage);
        if (file != null) {
            new Thread(() -> {
                try {
                    ObjectMapper mapper = new ObjectMapper();
                    long startTime = System.currentTimeMillis();
                    JsonNode root = mapper.readTree(file);
                    long loadTime = System.currentTimeMillis() - startTime;

                    Platform.runLater(() -> {
                        mainView.getLoadTimeLabel().setText("Load Time: " + loadTime + " ms");
                        TreeItem<String> rootItem = buildTree(root, "Root");
                        mainView.getJsonTreeView().setRoot(rootItem);
                        currentRootItem = rootItem;
                        navigationStack.clear();
                        currentPage = 1;
                        updatePagination();
                        if (!rootItem.getChildren().isEmpty()) rootItem.setExpanded(true);
                    });
                } catch (IOException e) {
                    Platform.runLater(() -> AlertUtil.showError("Error", "Failed to load file"));
                }
            }).start();
        }
    }

    public void handleSearch() {
        String keyword = mainView.getSearchField().getText().trim().toLowerCase();
        if (keyword.isEmpty()) return;

        searchMatches.clear();
        mainView.getJsonTreeView().setCellFactory(null);

        new Thread(() -> {
            collectMatches(mainView.getJsonTreeView().getRoot(), keyword, searchMatches);
            Platform.runLater(() -> {
                if (!searchMatches.isEmpty()) {
                    mainView.getJsonTreeView().setCellFactory(tv -> new HighlightTreeCell(searchMatches));
                    mainView.getJsonTreeView().refresh();
                    expandParents(searchMatches.get(0));
                    mainView.getJsonTreeView().getSelectionModel().select(searchMatches.get(0));
                    mainView.getJsonTreeView().scrollTo(mainView.getJsonTreeView().getRow(searchMatches.get(0)));
                }
            });
        }).start();
    }

    public int getCurrentPage() {
        return currentPage;
    }

    public void setCurrentPage(int currentPage) {
        this.currentPage = currentPage;
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public int getTotalPages() {
        return totalPages;
    }

    public void setTotalPages(int totalPages) {
        this.totalPages = totalPages;
    }

    public Deque<TreeItem<String>> getNavigationStack() {
        return navigationStack;
    }


    public JsonNode getRootNode() {
        return rootNode;
    }

    public void setRootNode(JsonNode rootNode) {
        this.rootNode = rootNode;
    }

    public TreeItem<String> getCurrentRootItem() {
        return currentRootItem;
    }

    public void setCurrentRootItem(TreeItem<String> currentRootItem) {
        this.currentRootItem = currentRootItem;
    }

    public List<TreeItem<String>> getSearchMatches() {
        return searchMatches;
    }

    public void setSearchMatches(List<TreeItem<String>> searchMatches) {
        this.searchMatches = searchMatches;
    }

    // 其他方法（分页、导航等）
    // 保持原始代码逻辑，调整参数传递方式
}